package com.awspaas.user.apps.shhtaerospaceindustrial.event;

import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.actionsoft.bpms.bpmn.engine.core.delegate.ProcessExecutionContext;
import com.actionsoft.bpms.bpmn.engine.listener.InterruptListenerInterface;
import com.actionsoft.bpms.commons.database.ColumnMapRowMapper;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.exception.BPMNError;
import com.awspaas.user.apps.shhtaerospaceindustrial.util.CoreUtil;

/**
 * 
 * @Description:表单办理前校验，检查被访单位的接待人是否存在
 * @author: dingyi
 * @date: 2023年7月14日 下午9:42:30
 */
public class checkInnerLocVisitValidateEvent implements InterruptListenerInterface {

	@Override
	public String getDescription() {

		return "表单办理前校验，参观地点时间冲突，阻止办理  ";
	}

	@Override
	public String getProvider() {

		return "wanghb";
	}

	@Override
	public String getVersion() {

		return "1.0";
	}

	@Override
	public boolean execute(ProcessExecutionContext processExecutionContext) throws Exception {
		// 获取流程实例ID
		String processInstId = processExecutionContext.getProcessInstance().getId();
		// 根据流程实例ID获取任务表内数据
		List<Map<String, Object>> visitmain = DBSql.query("SELECT * FROM BO_EU_INNERLOCATION_VISIT_APP WHERE BINDID = ? ",
				new ColumnMapRowMapper(), new Object[] { processInstId });
		List<Map<String, Object>> userinfolist = DBSql.query("SELECT * FROM BO_EU_INNLOC_VISIT_APP_PSNS WHERE BINDID = ? ",
				new ColumnMapRowMapper(), new Object[] { processInstId });
		List<Map<String, Object>> locinfolist = DBSql.query("SELECT * FROM BO_EU_INNLOC_VISIT_APP_LOCS WHERE BINDID = ? ",
				new ColumnMapRowMapper(), new Object[] { processInstId });
		List<Map<String, Object>> carsinfolist = DBSql.query("SELECT * FROM BO_EU_INNLOC_VISIT_APP_CARS WHERE BINDID = ? ",
				new ColumnMapRowMapper(), new Object[] { processInstId });

		

		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String today = sdf.format(date);
		long formatDateL = sdf.parse(today).getTime();
		long inTime = 0;
		long outTime = 0;
		for (Map<String, Object> map : visitmain) {
			//String TARGETMAN = CoreUtil.objToStr(map.get("TARGETMAN"));// 被访客姓名
			//String TARGETDEPT = CoreUtil.objToStr(map.get("TARGETDEPT"));// 被访部门
			//String TARGETUNIT = CoreUtil.objToStr(map.get("TARGETUNIT"));// 被访单位
			String PSNFILE = CoreUtil.objToStr(map.get("PSNFILE"));// 人员附件
			
			if (userinfolist == null || userinfolist.isEmpty()) {
				if("".equals(PSNFILE)) {
					throw new BPMNError("人员明细为空，请添加人员信息或者上传人员清单附件交");
				}
				
			}
		}
		//检查参观地点
		List<String> locslist = new ArrayList<String>();
		for (Map<String, Object> map : locinfolist) {
			String TARGETUNIT = CoreUtil.objToStr(map.get("TARGETUNIT"));// 单位
			String LOCATIONNAME = CoreUtil.objToStr(map.get("LOCATIONNAME"));// 地点
			locslist.add(LOCATIONNAME);
			String VISITDATE = CoreUtil.objToStr(map.get("VISITDATE"));// 日期
			String VISITDATETIME = CoreUtil.objToStr(map.get("VISITDATETIME"));// 时间
			String VISITDATETIMEEND = CoreUtil.objToStr(map.get("VISITDATETIMEEND"));// 时间
			if("".equals(VISITDATE)||"".equals(VISITDATETIME)||"".equals(VISITDATETIMEEND)) {
				throw new BPMNError("预计参观日期和参观时间不能为空！");
			}
			
			String[] starttimefield=VISITDATETIME.split(":");
	    	Integer starthour1=new Integer(starttimefield[0]);
	    	Integer startmin1=new Integer(starttimefield[1]);
			LocalTime start1 = LocalTime.of(starthour1, startmin1);
			String[] endtimefield=VISITDATETIMEEND.split(":");
	    	Integer endhour1=new Integer(endtimefield[0]);
	    	Integer endmin1=new Integer(endtimefield[1]);			
	        LocalTime end1 = LocalTime.of(endhour1, endmin1);
			
			String udate = CoreUtil.objToStr(map.get("VISITDATE"));// 进入
			long udateL = sdf.parse(udate).getTime();
			if (udateL < formatDateL) {// 如果进入日期小于系统日期
				throw new BPMNError(TARGETUNIT+LOCATIONNAME+VISITDATETIME+"预计参观日期时间不能小于当前日期！");
			}		
			//日期重复检查
			String queryRecordSql = "select t.targetunit,t.targetman,t.targetmanphone,  a.visitdate, a.visitdatetime, a.visitdatetimeend, t.bindid " + 
					"  from BO_EU_INNERLOCATION_VISIT_APP t, BO_EU_INNLOC_VISIT_APP_LOCS a " + 
					" where t.bindid = a.bindid  and a.TARGETUNIT='"+TARGETUNIT+"' and  a.LOCATIONNAME='"+LOCATIONNAME+"' and t.bindid !='"+processInstId+"' " + 
					"   and  t.BUSISTATUS in ('1','2') and to_date(a.visitdate, 'yyyy-MM-dd')=to_date('"+udate+"', 'yyyy-MM-dd')";
			System.out.println(queryRecordSql);
			List<Map<String, Object>> RecordList = DBSql.query(queryRecordSql, new ColumnMapRowMapper(),
					new Object[] {});
			//System.out.println("历史记录："+RecordList.size());
			
			for(int i = 0; i< RecordList.size(); i++) {
				Map<String, Object> recordMap = RecordList.get(i);
				String TTUNIT = CoreUtil.objToStr(recordMap.get("TARGETUNIT"));// 单位
				String TARGETMAN = CoreUtil.objToStr(recordMap.get("TARGETMAN"));// 单位
				String TARGETMANPHONE = CoreUtil.objToStr(recordMap.get("TARGETMANPHONE"));// 单位
				String visitdate = CoreUtil.objToStr(recordMap.get("visitdate"));// 单位
				String visitdatetime = CoreUtil.objToStr(recordMap.get("visitdatetime"));// 单位
				String visitdatetimeend = CoreUtil.objToStr(recordMap.get("visitdatetimeend"));// 单位
				
				String[] starttimefield2=visitdatetime.split(":");
		    	Integer starthour2=new Integer(starttimefield2[0]);
		    	Integer startmin2=new Integer(starttimefield2[1]);
				LocalTime start2 = LocalTime.of(starthour2, startmin2);
				String[] endtimefield2=visitdatetimeend.split(":");
		    	Integer endhour2=new Integer(endtimefield2[0]);
		    	Integer endmin2=new Integer(endtimefield2[1]);			
		        LocalTime end2 = LocalTime.of(endhour2, endmin2);
				
		        boolean overlap = isTimeOverlap(start1, end1, start2, end2);
		        if (overlap) {
		        	throw new BPMNError(TTUNIT+","+TARGETMAN+","+TARGETMANPHONE+","+visitdate+" "+visitdatetime+" 存在重复预约，请重新选择时间地点.");
		        } else {
		           continue;
		        }
			}
			
			
			
		}
		long locscount = locslist.stream().distinct().count();
		List dumplist = locslist.stream()

				.collect(Collectors.toMap(e -> e, e -> 1, Integer::sum))

				.entrySet()

				.stream()

				.filter(e -> e.getValue() > 1)

				.map(Map.Entry::getKey)

				.collect(Collectors.toList());
		if (dumplist.size() > 0) {
			String certstr = "";
			for (Object val : dumplist) {
				certstr = (String) val + ";";
			}
			System.out.println(certstr);
			throw new BPMNError("参观地点填写重复：" + certstr);
		}
		//检查车辆
		List<String> carslist = new ArrayList<String>();
	
		for (Map<String, Object> map : carsinfolist) {
			String CARNO = CoreUtil.objToStr(map.get("CARNO"));
			carslist.add(CARNO);
		}	
		long carscount = carslist.stream().distinct().count();
		List dumplist2 = carslist.stream()

				.collect(Collectors.toMap(e -> e, e -> 1, Integer::sum))

				.entrySet()

				.stream()

				.filter(e -> e.getValue() > 1)

				.map(Map.Entry::getKey)

				.collect(Collectors.toList());
		if (dumplist2.size() > 0) {
			String certstr = "";
			for (Object val : dumplist2) {
				certstr = (String) val + ";";
			}
			System.out.println(certstr);
			throw new BPMNError("车辆号码填写重复：" + certstr);
		}

		String queryloc = "SELECT count(id)  as sastcount FROM BO_EU_INNLOC_VISIT_APP_LOCS WHERE bindid=  '" + processInstId
				+ "' AND TARGETUNIT in ('院部','805所')";
		int sastcount = CoreUtil.objToInt(DBSql.getString(queryloc, "sastcount"));// 根据查询是否有参观院部展示厅
		//检查如果要参观院部展示厅，必须指定进出航天城园区门号
		if(sastcount>0) 
		{
		for (Map<String, Object> map : carsinfolist) {
			String INOUTDOOR = CoreUtil.objToStr(map.get("INOUTDOOR"));// 单位
			if("".equals(INOUTDOOR)) {
				throw new BPMNError("参观航天城园区展厅，需指定车辆进入航天城园区门号.");
			}
		}
		}
			
		

		return true;
	}
	/**
     * 验证时间是否重叠
     *  @return boolean*/
	public static boolean isTimeOverlap(LocalTime start1, LocalTime end1, LocalTime start2, LocalTime end2) {
        if (start1.isBefore(start2) && end1.isAfter(start2)) {
            return true; // 时间段1的结束时间晚于时间段2的开始时间，且时间段1的开始时间早于时间段2的结束时间
        }

        if (start2.isBefore(start1) && end2.isAfter(start1)) {
            return true; // 时间段2的结束时间晚于时间段1的开始时间，且时间段2的开始时间早于时间段1的结束时间
        }

        if (start1.equals(start2) || end1.equals(end2)) {
            return true; // 时间段1的开始时间与时间段2的开始时间相同，或者时间段1的结束时间与时间段2的结束时间相同
        }

        return false; // 没有重叠
    }

}
